home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
smaltalk
/
st80_pr4.lha
/
st80_pre4
/
Foible
/
foible
/
Icon-Tools.st
< prev
next >
Wrap
Text File
|
1993-07-24
|
21KB
|
760 lines
'From Tektronix Smalltalk-80 version T2.2.0cM3, of September 21, 1987 on 3 May 1990 at 3:26:27 pm'!
BitEditor subclass: #IconEditor
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Icon-Tools'!
IconEditor comment:
'I am the icon editor that IconManager uses to edit its icons. I have an
unscheduled view. A real-size view of the icon displayed in my palette.'!
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
IconEditor class
instanceVariableNames: ''!
!IconEditor class methodsFor: 'editing forms'!
editIcon: anIcon
"Bit editing of an area of the display screen. User designates a
rectangular area that is magnified by 8 to allow individual screens dots to be
modified. Editor is not scheduled in a view. Original screen location is
updated immediately."
| scaleFactor tempRect |
scaleFactor _ 8 @ 8.
tempRect _ self locateMagnifiedView: anIcon scale: scaleFactor.
"show magnified form size until mouse is depressed"
self
openScreenViewOnForm: anIcon
magnifiedAt: tempRect topLeft
scale: scaleFactor! !
!IconEditor class methodsFor: 'instance creation'!
openScreenViewOnForm: aForm magnifiedAt: magnifiedLocation scale: scaleFactor
"Create and schedule a BitEditor on the form aForm"
| bitEditor savedForm |
bitEditor _ self bitEdit: aForm at: magnifiedLocation scale: scaleFactor remoteView: nil.
savedForm _ Form fromDisplay: (Rectangle origin: bitEditor labelDisplayBox topLeft corner: bitEditor displayBox corner).
bitEditor controller blueButtonMenu: nil blueButtonMessages: nil.
bitEditor controller startUp.
savedForm displayOn: Display at: bitEditor labelDisplayBox topLeft.
bitEditor release! !
!IconEditor class methodsFor: 'class initialization'!
initialize
"IconManager initialize."
YellowButtonMenu _ PopUpMenu labels:
'accept
cancel'.
YellowButtonMessages _ #(accept cancel)! !
IconEditor initialize!
ScrollController subclass: #IconEditorController
instanceVariableNames: 'bottomScrollBar bottomMarker bottomSavedArea '
classVariableNames: ''
poolDictionaries: ''
category: 'Icon-Tools'!
IconEditorController comment:
'I am the controller for IconView. We are used in an icon browser to
provide a view of the icon. I implement the ability to scroll the view of
the icon both horizontally and vertically.'!
!IconEditorController methodsFor: 'initialize-release'!
initialize
super initialize.
bottomScrollBar _ Quadrangle new.
bottomScrollBar borderWidthLeft: 2 right: 2 top: 0 bottom: 2.
bottomMarker _ Quadrangle new.
bottomMarker insideColor: Form gray.! !
!IconEditorController methodsFor: 'control sequence'!
controlInitialize
super controlInitialize.
bottomScrollBar region: (0@0 extent: (view displayBox width + 2) @ 32).
bottomMarker region: self computeBottomMarkerRegion.
bottomScrollBar _ bottomScrollBar align: bottomScrollBar topLeft with: view displayBox bottomLeft - (1@0).
bottomMarker _ bottomMarker align: bottomMarker leftCenter with: bottomScrollBar inside leftCenter.
bottomSavedArea _ Form fromDisplay: bottomScrollBar.
bottomScrollBar displayOn: Display.
self moveBottomMarker!
controlTerminate
super controlTerminate.
bottomSavedArea notNil
ifTrue:
[bottomSavedArea displayOn: Display at: bottomScrollBar topLeft.
bottomSavedArea _ nil ]! !
!IconEditorController methodsFor: 'scrolling'!
bottomScroll
"Check to see whether the user wishes to jump, scroll left, or scroll right."
| savedCursor regionPercent |
savedCursor _ sensor currentCursor.
[self bottomScrollBarContainsCursor]
whileTrue:
[Processor yield.
regionPercent _ 100 * ( bottomScrollBar inside bottom - sensor cursorPoint y ) // bottomScrollBar height.
regionPercent <= 40
ifTrue: [self scrollLeft]
ifFalse: [regionPercent >= 60
ifTrue: [self scrollRight]
ifFalse: [self bottomScrollAbsolute]]].
savedCursor show!
bottomScrollAmount
^ ((view inverseDisplayTransform: sensor cursorPoint)
- (view inverseDisplayTransform: bottomScrollBar inside leftCenter )) x!
bottomScrollView
self bottomScrollView: self bottomViewDelta!
bottomScrollView: anInteger
| maximumAmount minimumAmount amount |
maximumAmount _
view clippingRectangle left -
view compositionRectangle left max: 0.
minimumAmount _
view clippingRectangle right -
view compositionRectangle right min: 0.
amount _
(anInteger min: maximumAmount) max:
minimumAmount.
amount ~= 0
ifTrue:
[view scrollBy: amount@0]!
bottomViewDelta
^view clippingRectangle left - view compositionRectangle left -
(( bottomMarker left - bottomScrollBar inside left ) asFloat /
bottomScrollBar inside width asFloat *
view compositionRectangle width asFloat ) rounded!
canBottomScroll
^ (bottomMarker region width < bottomScrollBar inside width)!
canScrollDown
^self canScroll and: [marker region top > scrollBar inside top]!
canScrollLeft
^self canBottomScroll and: [bottomMarker region right < bottomScrollBar inside right]!
canScrollRight
^self canBottomScroll and: [bottomMarker region left > bottomScrollBar inside left]!
canScrollUp
"Answer whether there is information that is not visible and can be seen
by scrolling up."
^self canScroll and: [marker region bottom < scrollBar inside bottom]!
scrollView: anInteger
| maximumAmount minimumAmount amount |
maximumAmount _
view clippingRectangle top -
view compositionRectangle top max: 0.
minimumAmount _
view clippingRectangle bottom -
view compositionRectangle bottom min: 0.
amount _
(anInteger min: maximumAmount) max:
minimumAmount.
amount ~= 0
ifTrue:
[view scrollBy: 0@amount ]!
scrollViewLeft
self bottomScrollView: self bottomScrollAmount negated!
scrollViewRight
self bottomScrollView: self bottomScrollAmount!
viewDelta
^(view clippingRectangle top -
view compositionRectangle top -
((marker top - scrollBar inside top) asFloat /
scrollBar inside height asFloat *
view compositionRectangle height asFloat)) rounded! !
!IconEditorController methodsFor: 'private'!
bottomScrollAbsolute
| oldBottomMarker |
self changeCursor: Cursor up.
self canBottomScroll & sensor anyButtonPressed ifTrue:
[[sensor anyButtonPressed ] whileTrue:
[oldBottomMarker _ bottomMarker.
bottomMarker _ bottomMarker translateBy:
((sensor cursorPoint x - bottomMarker center x
min: bottomScrollBar inside right - bottomMarker right)
max: bottomScrollBar inside left - bottomMarker left) @ 0.
(oldBottomMarker areasOutside: bottomMarker ) ,
( bottomMarker areasOutside: oldBottomMarker ) do:
[ :region | Display fill: region rule: Form reverse
mask: Form gray ]. self bottomScrollView ].
bottomScrollBar display.
self moveBottomMarker ]!
scrollAbsolute
| oldMarker |
self changeCursor: Cursor marker.
self canScroll & sensor anyButtonPressed ifTrue:
[[sensor anyButtonPressed] whileTrue:
[ oldMarker _ marker.
marker _ marker translateBy:
0@((sensor cursorPoint y - marker center y min:
scrollBar inside bottom - marker bottom) max: scrollBar inside top - marker top).
(oldMarker areasOutside: marker), (marker areasOutside: oldMarker) do:
[:region | Display fill: region rule: Form reverse mask: Form gray]. self scrollView].
scrollBar display.
self moveMarker]!
scrollLeft
| delay |
self changeCursor: (Cursor marker rotateBy: 2) "up left".
delay _ Delay forMilliseconds: self scrollDelayLength.
self canScrollLeft ifTrue: [[sensor anyButtonPressed]
whileTrue: [self canScrollLeft
ifTrue:
[self scrollViewLeft.
self moveBottomMarker].
delay wait]]!
scrollRight
| delay |
self changeCursor: Cursor marker "right".
delay _ Delay forMilliseconds: self scrollDelayLength.
self canScrollRight ifTrue: [[sensor anyButtonPressed]
whileTrue: [self canScrollRight
ifTrue:
[self scrollViewRight.
self moveBottomMarker].
delay wait]]!
scrollUp
"Scroll the text up a relative amount. Don't go faster than the user's reaction time."
| delay |
self changeCursor: Cursor up.
delay _ Delay forMilliseconds: self scrollDelayLength.
self canScrollUp ifTrue: [[sensor anyButtonPressed]
whileTrue: [self canScrollUp
ifTrue:
[self scrollViewUp.
self moveMarker].
delay wait]]! !
!IconEditorController methodsFor: 'cursor'!
bottomMarkerContainsCursor
^ bottomMarker inside containsPoint: sensor cursorPoint!
bottomScrollBarContainsCursor
^ bottomScrollBar inside containsPoint: sensor cursorPoint! !
!IconEditorController methodsFor: 'control defaults'!
controlActivity
self bottomScrollBarContainsCursor
ifTrue: [self bottomScroll ]
ifFalse: [super controlActivity ]!
isControlActive
^ self bottomScrollBarContainsCursor | super isControlActive! !
!IconEditorController methodsFor: 'marker adjustment'!
bottomMarkerDelta
^ bottomMarker left
- bottomScrollBar inside left
- (( view insetDisplayBox left - view compositionRectangle left) asFloat
/ model form width asFloat *
bottomScrollBar inside width asFloat) rounded!
bottomMarkerRegion: aRectangle
Display fill: bottomMarker mask: bottomScrollBar insideColor.
bottomMarker region: aRectangle.
bottomMarker _ bottomMarker align: bottomMarker leftCenter with: bottomScrollBar inside leftCenter!
computeBottomMarkerRegion
^ 0@0 extent: (( view insetDisplayBox width asFloat /
model form width * bottomScrollBar inside width) rounded
min: bottomScrollBar inside width) @ 10!
computeMarkerRegion
"Answer the rectangular area in which the gray area of the scroll bar
should be displayed."
^0@0 extent: 10 @
((view insetDisplayBox height asFloat /
model form height *
scrollBar inside height)
rounded min: scrollBar inside height)!
markerDelta
^marker top
- scrollBar inside top
- ((view insetDisplayBox top - view compositionRectangle top) asFloat
/ model form height asFloat *
scrollBar inside height asFloat) rounded!
moveBottomMarker
self moveBottomMarker: self bottomMarkerDelta negated!
moveBottomMarker: anInteger
Display fill: bottomMarker mask: bottomScrollBar insideColor.
bottomMarker _ bottomMarker translateBy: ( (anInteger
min: bottomScrollBar inside right - bottomMarker right)
max: bottomScrollBar inside left - bottomMarker left) @ 0 .
bottomMarker displayOn: Display! !
!IconEditorController methodsFor: 'scroll bar region'!
repaintUnderBottomScrollBar
bottomSavedArea notNil
ifTrue:
[ bottomSavedArea displayOn: Display at: bottomScrollBar topLeft.
bottomSavedArea _ nil ]!
repaintUnderScrollBar
super repaintUnderScrollBar.
self repaintUnderBottomScrollBar! !
Object subclass: #IconManager
instanceVariableNames: 'iconDict currentIcon directory '
classVariableNames: ''
poolDictionaries: ''
category: 'Icon-Tools'!
IconManager comment:
'I am an interface to editing,creating and retreiving icons stored on disk.
An icon browser can be created with my class method openOnDir:. See
the method newIconExtent in "accessing" for defining the size of newly
created icon.
I also have a class method, getIcon: fromDirectory:, that is used by other
classes, to retrieve their icons, so that they do not have to be hard-coded
in their initialize method.
NOTE:
Several of my methods have a ''/'' hardcoded in for use when dealing with
directories. This only works in a Unix-like environment. DOS or Mac
users will have to change the character appropriately.
My instance variables, which are only used when I create an icon browser, are:
iconDict dictionary that keeps track of icons, once in memory
currentIcon the name of the currently selected icon
directory the directory that I am managing'!
!IconManager methodsFor: 'accessing'!
currentIcon
^currentIcon!
dirFullName
^directory fullName!
form
" return the form for the current icon. if I have not read the form in from disk,
then read it in and store it in my dictionary "
| theIcon |
currentIcon=nil ifTrue:[^Form extent: 1@1].
theIcon_iconDict at: currentIcon.
theIcon isNil
ifTrue:[theIcon_Form readFrom: self pathToCurrent.
iconDict at: currentIcon put: theIcon].
^theIcon!
icon: aName
currentIcon_aName.
self changed: #form!
iconList
iconDict isNil ifTrue: [^nil]
ifFalse: [^iconDict keys asSortedCollection]!
newIconExtent
"return the size of new icons that are added to the library"
^40@50!
pathToCurrent
"return the full path to the current icon"
^self dirFullName,currentIcon! !
!IconManager methodsFor: 'initialize/release'!
initDict: aDirName
" set up the dictionary of icons, ignore *.bak files "
directory _ Disk directoryNamed: aDirName.
directory exists
ifFalse: [PopUpNotifier message: 'Error: directory does not exist'.
^nil].
iconDict _ Dictionary new.
directory namesDo:
[:each | ('*.bak' match: each)
ifFalse: [(iconDict at: each ifAbsent: [nil]) isNil
ifTrue: [iconDict at: each put: nil]]]! !
!IconManager methodsFor: 'menu'!
addIcon
| newIcon iconName fullName|
iconName_FillInTheBlank request: 'New Icon Name' initialAnswer: ('').
iconName='' ifTrue: [^self].
iconDict isNil ifTrue: [iconDict_Dictionary new].
fullName_self dirFullName,iconName.
(FileStream fileNamed: fullName) exists
ifFalse:[newIcon_Form extent: self newIconExtent.
newIcon writeOn: fullName]
ifTrue:[PopUpNotifier message: 'An icon with this name already exists in this directory'.
^nil].
iconDict at: iconName put: newIcon.
currentIcon_iconName.
self changed: #icon!
changeDir
| newDir fullName |
newDir _ FillInTheBlank request: 'New Directory:' initialAnswer: (self dirFullName).
newDir = '' ifTrue: [^nil].
(Disk directoryNamed: newDir) exists
ifFalse: [PopUpNotifier message: 'directory ',newDir,' does not exist'.
^nil].
self initDict: newDir.
self changed: #icon!
copyIcon
| copyDir fullName |
copyDir _ FillInTheBlank request: 'Directory to Copy Icon to:' initialAnswer: (self dirFullName).
copyDir = '' ifTrue: [^self].
(Disk directoryNamed: copyDir) exists
ifFalse: [PopUpNotifier message: 'directory ',copyDir,' does not exist'.
^nil].
copyDir _ copyDir,'/',currentIcon.
iconDict isNil ifTrue: [iconDict _ Dictionary new].
fullName _ self pathToCurrent.
directory copy: fullName to: copyDir!
editIcon
| theIcon |
theIcon_iconDict at: currentIcon.
IconEditor editIcon: theIcon.
theIcon writeOn: self pathToCurrent.
self changed: #form!
iconMenu
" the menu changes depending on whether an icon is selected or not"
currentIcon=nil
ifTrue:[^ActionMenu labels: 'add new icon
change directory
update icon list' withCRs
selectors: #(addIcon changeDir updateList)].
^ActionMenu
labels: 'add new icon
edit icon
icon code
rename icon
remove icon
copy icon
change directory
update icon list' withCRs
selectors: #(addIcon editIcon openCodeView renameIcon removeIcon copyIcon changeDir updateList)!
openCodeView
"Open a window with a code description of the currently displayed icon"
| aStream |
aStream _ WriteStream on: (String new: 1000).
self form storeOn: aStream base: 10.
StringHolderView open: (StringHolder new contents: aStream contents)
label: 'Code for ',currentIcon!
removeIcon
| file |
file _ Disk file: self pathToCurrent.
(file exists and: [(BinaryChoice message: 'Are you sure that you want to delete ',currentIcon,'?')])
ifTrue:[file remove.
iconDict removeKey: currentIcon.
currentIcon_nil.
self changed: #icon]!
renameIcon
| newName fullName file |
newName_FillInTheBlank request: 'New Icon Name' initialAnswer: (currentIcon).
newName='' ifTrue: [^self].
fullName_ self dirFullName,newName.
(FileStream fileNamed: fullName) exists
ifTrue:[PopUpNotifier message: 'An icon with this name already exists in this directory'.
^nil].
(iconDict at:currentIcon) writeOn: fullName.
iconDict at: newName put: (iconDict at: currentIcon).
iconDict removeKey: currentIcon.
file _ Disk file: self pathToCurrent.
file exists ifTrue:[file remove].
currentIcon_newName.
self changed: #icon!
updateList
" update the listing of the directory"
self initDict: self dirFullName.
self changed: #icon! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
IconManager class
instanceVariableNames: ''!
!IconManager class methodsFor: 'view creation'!
openOnDir: aDir
" open an icon browser on the directory named aDir"
"IconManager openOnDir: '<directory name>'."
| topView listView formView iconDictionary |
(Disk directoryNamed: aDir) exists
ifFalse: [PopUpNotifier message: 'Error: directory does not exist'.
^nil].
iconDictionary _ self new initDict: aDir.
topView_StandardSystemView
model: iconDictionary
label: 'directory:',aDir
minimumSize: 50@50.
topView borderWidth: 1.
listView_SelectionInListView
on:iconDictionary
aspect: #icon
change: #icon:
list: #iconList
menu: #iconMenu
initialSelection: #currentIcon.
formView_IconEditorView
on: iconDictionary
aspect: #form
menu: #iconMenu.
topView addSubView: listView
in: (0@0 extent: 1@0.6)
borderWidth: 1.
topView addSubView: formView
in: (0@0.6 extent: 1@0.4)
borderWidth: 1.
topView controller open! !
!IconManager class methodsFor: 'retrieving forms'!
formToCursor: aForm
^Cursor extent: aForm extent
fromArray: aForm bits
offset: aForm offset!
getCursor: iconName fromDirectory: dirName
" retrieve an icon from disk "
| directory |
directory _ Disk directoryNamed: dirName.
directory exists
ifFalse: [self error: 'Forms directory ',dirName,' does not exist'.
^nil].
directory namesDo:
[:each | (iconName match: each)
ifTrue: [^self formToCursor: (Form readFrom: dirName,'/',iconName)]].
self error: 'Cannot find icon ',iconName,' in directory ',dirName.
^nil!
getIcon: iconName fromDirectory: dirName
" retrieve an icon from disk "
| directory |
directory _ Disk directoryNamed: dirName.
directory exists
ifFalse: [self error: 'Forms directory ',dirName,' does not exist'.
^nil].
directory namesDo:
[:each | (iconName match: each)
ifTrue: [^Form readFrom: dirName,'/',iconName]].
self error: 'Cannot find icon ',iconName,' in directory ',dirName.
^nil! !
FormView subclass: #IconEditorView
instanceVariableNames: 'clippingRectangle formMsg menuMsg scrollOffset '
classVariableNames: ''
poolDictionaries: ''
category: 'Icon-Tools'!
IconEditorView comment:
'I am the view in an icon browser that provides a view of the icon.'!
!IconEditorView methodsFor: 'updating'!
update: aSymbol
| form |
aSymbol == formMsg
ifTrue: [form _ self getForm.
form isNil
ifFalse:[self scrollOffset:0@0.
self displayView].
super update: aSymbol]! !
!IconEditorView methodsFor: 'private'!
clippingRectangle
^clippingRectangle!
clippingRectangle: aRect
clippingRectangle_aRect!
compositionRectangle
^Rectangle origin: self scrollOffset+self clippingRectangle origin extent: self getForm extent!
on: anObject aspect: m1 menu: m4
self model: anObject.
formMsg _ m1.
menuMsg _ m4.
self initialize!
scrollOffset
^scrollOffset!
scrollOffset: aPoint
scrollOffset_aPoint! !
!IconEditorView methodsFor: 'window access'!
defaultWindow
^(Rectangle origin: 0 @ 0 extent: self getForm extent)
expandBy: borderWidth! !
!IconEditorView methodsFor: 'displaying'!
display
self isUnlocked ifTrue: [self scrollOffset:0@0].
self displayBorder.
self displayView.
self noSelectionSelected.!
displayView
self clippingRectangle: self insetDisplayBox.
self clearInside: Form lightGray.
insideColor == nil ifFalse: [Display fill: self insetDisplayBox mask: insideColor].
(self getForm)
displayOn: Display
at: (self insetDisplayBox origin) + self scrollOffset
clippingBox: self clippingRectangle
rule: self rule
mask: self mask! !
!IconEditorView methodsFor: 'controller access'!
defaultControllerClass
^IconEditorController! !
!IconEditorView methodsFor: 'scrolling'!
scrollBy: aPoint
"The x component of aPoint specifies the amount of scrolling in the x direction;
the y component specifies the amount of scrolling in the y direction. The amounts
are specified in the receiver's local coordinate system."
self scrollOffset: self scrollOffset + aPoint.
self display! !
!IconEditorView methodsFor: 'adaptor'!
getForm
| form |
formMsg == nil ifTrue: [^nil].
form _ model perform: formMsg.
^ form! !
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!
IconEditorView class
instanceVariableNames: ''!
!IconEditorView class methodsFor: 'instance creation'!
on: anObject aspect: aspectMsg menu: menuMsg
"Create a 'pluggable' (see class comment) formView viewing anObject.
aspectMsg is sent to read the current form in the model.
It is also used as the changed: parameter for this view."
| pfView |
pfView_self new on: anObject aspect: aspectMsg menu: menuMsg.
pfView scrollOffset: 0@0.
^pfView! !